<?php

namespace app\api\controller\v1;

use app\api\controller\BaseController;
use app\api\validate\IDMustBePostiveInt;
use app\api\validate\OrderPlace;
use app\api\validate\PagingParamter;
use app\api\service\Token as TokenService;
use app\api\service\Order as OrderService;
use app\api\model\Order as OrderModel;
use app\lib\exception\OrderException;
use app\lib\exception\SuccessMessage;
use think\Db;
use think\Request;

class Order extends BaseController{
	// 用户在选择商品后,向api提交包含它所选择商品的相关信息
	// api在接收到信息后,需要检查订单相关商品的库存量
	// 有库存,把订单数据存入到数据库中 = 下单成功了,返回客户端消息,告诉客户端可以支付了
	// 调用我们的支付接口,进行支付
	// 还需要再次进行库存量检测
	// 服务器这边就可以调用的微信的支付接口进行支付
	// 小程序根据服务器返回的结果拉起微信支付
	// 微信会返回给我们一个支付的结果(异步) 返回两个,一个到客户端,一个到服务器端
	// 成功:也需要进行库存量的检测
	// 成功:进行库存量的扣除

	// 另一种思路处理库存量的问题
	// 先库存量检测
	// 创建订单
	// 减库存 -- 预扣除库存
	// if pay 真正的减库存
	// 在一定时间内(15min)没有支付这个订单, 我们需要还原库存

	// 还原的方法
	// 在PHP里写一个定时器, 每隔1min去遍历数据库,
	// 找到那些超时的订单, 把这些订单给还原库存
	// linux crontab

	// 任务队列
	// 订单任务加入到队列里
	// redis

	// 定时器, 每隔1s, 5s, 访问API的接口

	protected $beforeActionList = [
		'checkExclusiveScope' => ['only' => 'placeOrder'],
		'checkPrimaryScope' => ['only' => 'getSummaryByUser, getDetail'],
	];

    /**
     * 获取分销订单
     */
    public function orders()
    {
        $token = Request::instance()->header('token');

        if($token){
            $uid = TokenService::getCurrentUid();
            $data = OrderModel::getOrders($uid);
        }else{
            // 随便获取几条订单数据
            $data = OrderModel::getCasualOrders();
        }

        $result = [];
        $result['msg'] = 'success';
        $result['error_code'] = 0;
        $result['data'] = $data;

        return $result;
    }

    /**
     * @return array
     * 向数据库添加新订单
     * @throws \app\lib\exception\ParameterException
     */
    public function addOrder()
    {
        $data['ordernum'] = '26486516514';
        $data['goods'] = 'Type-C耳机四核双动圈接口小米8SE手机专用6X黑鲨note3半入耳式耳塞小米9华为p20重低音Mate10Pro';
        $data['ordertime'] = date("Y-m-d");
        $data['money'] = 100;
        $data['shop_id'] = 1;
        $data['studio_id'] = 1;
        $data['dealer_id'] = 1;
        $data['consumer_id'] = 2;
        $data['name'] = '下单人姓名';
        $data['phone'] = '18888888888';
        $data['address'] = '下单人收货地址';
        $data['createtime'] = time();
        $add = Db::name('order')->insert($data);

        if($add){
            $money = 100;
            $dealer_id = 1;
            $consumer_id = 2;   // 上级分销用户
            $commission = Db::name('commission')
                ->where('dealer_id', $dealer_id)
                ->field('firstratio, secondratio, thirdratio')
                ->find();

            if (!$commission){
                throw new OrderException([
                    'msg' => '没有相关的佣金比设置'
                ]);
            }

            if($consumer_id){
                // 处理分润
                $result =  $this->shareProfit($money, $dealer_id, $consumer_id, $commission);

                return $result;
//                if($result['status'])
//                {
//                    return new SuccessMessage();
//                }else{
//                    throw new OrderException([
//                       'msg' => $result['msg']
//                    ]);
//                }
            }
        }else{
            throw new OrderException([
                'msg' => '添加订单失败'
            ]);
        }
    }

    /**
     * @return array
     * 分润
     * @throws \app\lib\exception\ParameterException
     */
    public function shareProfit($money, $dealer_id, $consumer_id, $commission, $level = 1)
    {
        // 获取分销用户信息
        $consumer = Db::name('consumer')
            ->where('id', $consumer_id)
            ->field('consumer_id,commission,distribution')
            ->find();
        switch ($level)
        {
            case 1:
                $ratio = 'firstratio';
                break;
            case 2:
                $ratio = 'secondratio';
                break;
            case 3:
                $ratio = 'thirdratio';
                break;
        }

        $commission_ratio = $commission[$ratio] / 100;
        $add_num = bcmul($money, $commission_ratio, 2);
        // 判断是否为经销商用户
        if($consumer['consumer_id']){
            // 不是，更新佣金和经销商的总分润
            Db::startTrans();
            try {
                Db::name('consumer')->where('id', $consumer_id)->setInc('commission', $add_num);
                Db::name('consumer')
                    ->where('dealer_id = '.$dealer_id.' and consumer_id = 0')
                    ->setInc('distribution', $add_num);
                Db::commit();
                $level += 1;
                $status = 1;
                $this->shareProfit($money, $dealer_id, $consumer['consumer_id'], $commission, $level);
            }
            catch (\Exception $ex)
            {
                Db::rollback();
                $status = 0;
            }
        }else{
            // 是，更新佣金数
            Db::name('consumer')->where('id', $consumer_id)->setInc('commission', $add_num);
            $status = 1;
        }

        return $status;
    }

    // 处理普通用户分润
    public function handleProfit($money, $dealer_id, $consumer_id, $commission, $is_dealer)
    {
        if ($is_dealer){
            // 如果是经销商
            Db::startTrans();
            try {
                $commission_num = $commission / 100;
                $add_num = bcmul($money, $commission_num, 2);
                Db::name('consumer')->where('id', $consumer_id)->setInc('commission', $add_num);
                Db::commit();

                return 1;
            }
            catch (\Exception $ex)
            {
                Db::rollback();

                return 0;
            }
        }else{
            // 如果不是经销商

        }
    }

    // 从抖店获取订单
    public function getDouOrder()
    {
        $order = new OrderService();
        $result = $order->getOrderFromDou();

        return $result;
    }

	// 下单
	public function placeOrder()
	{
		(new OrderPlace())->gocheck();
		$products = input('post.products/a');
		$uid = TokenService::getCurrentUid();

		$order = new OrderService();
		$status = $order->place($uid, $products);

		return $status;
	}

	/**
	 * @param int $page
	 * @param int $size
	 * 获取历史订单
	 * @return array
	 * @throws \app\lib\exception\ParameterException
	 */
	public function getSummaryByUser($page=1, $size=5)
	{
		(new PagingParamter())->goCheck();
		$uid = TokenService::getCurrentUid();
		$pagingOrders = OrderModel::getSummaryByUser($uid, $page, $size);

		if($pagingOrders->isEmpty()){

			return [
				'data' => [],
				'current_page' => $pagingOrders->getCurrentPage()
			];
		}
		$data = $pagingOrders->hidden(['snap_items','snap_address','prepay_id'])
			->toArray();

		 return [
		 	'data' => $data,
		 	'current_page' => $pagingOrders->getCurrentPage()
		 ];
	}

	/**
	 * @param $id
	 * 订单详情
	 * @return OrderModel
	 * @throws OrderException
	 * @throws \app\lib\exception\ParameterException
	 * @throws \think\exception\DbException
	 */
	public function getDetail($id)
	{
		(new IDMustBePostiveInt())->goCheck();
		$orderDetail = OrderModel::get($id);

		if(!$orderDetail){
			throw new OrderException();
		}

		return $orderDetail->hidden(['prepay_id']);
	}

	/**
	 * 获取全部订单简要信息(分页)-cms
	 * @param int $page
	 * @param int $size
	 * @return array
	 * @throws \app\lib\exception\ParameterException
	 */
	public function getSummary($page, $size = 10)
	{
		(new PagingParamter())->goCheck();

		$pagingOrders = OrderModel::getSummaryByPage($page, $size);

		if($pagingOrders->isEmpty()){
			return [
				'current_page' => $pagingOrders->currentPage(),
				'data' => []
			];
		}
		$data = $pagingOrders->hidden(['snap_items', 'snap_address'])
			->toArray();

		return [
			'current_page' => $pagingOrders->currentPage(),
			'data' => $data
		];
	}

	/**
	 * 发送模板消息
	 * @param int $id - 订单号Id
	 */
	public function delivery($id)
	{
		(new IDMustBePostiveInt())->goCheck();

		$order = new OrderService();
		$success = $order->delivery($id);

		if($success){
			return new SuccessMessage();
		}
	}
}